home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / Java2 / src / javax / swing / ScrollPaneLayout.java < prev    next >
Encoding:
Java Source  |  1999-05-28  |  26.7 KB  |  908 lines  |  [TEXT/CWIE]

  1. /*
  2.  * @(#)ScrollPaneLayout.java    1.32 98/10/06
  3.  *
  4.  * Copyright 1997, 1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package javax.swing;
  16.  
  17.  
  18. import javax.swing.border.*;
  19.  
  20. import java.awt.LayoutManager;
  21. import java.awt.Component;
  22. import java.awt.Container;
  23. import java.awt.Rectangle;
  24. import java.awt.Dimension;
  25. import java.awt.Insets;
  26. import java.io.Serializable;
  27.  
  28.  
  29. /**
  30.  * The layout manager used by JScrollPane.  JScrollPaneLayout is
  31.  * responsible for nine components: a viewport, two scrollbars,
  32.  * a row header, a column header, and four "corner" components.
  33.  * <p>
  34.  * <strong>Warning:</strong>
  35.  * Serialized objects of this class will not be compatible with
  36.  * future Swing releases.  The current serialization support is appropriate
  37.  * for short term storage or RMI between applications running the same
  38.  * version of Swing.  A future release of Swing will provide support for
  39.  * long term persistence.
  40.  *
  41.  * @see JScrollPane
  42.  * @see JViewport
  43.  *
  44.  * @version 1.32 10/06/98
  45.  * @author Hans Muller
  46.  */
  47. public class ScrollPaneLayout
  48.     implements LayoutManager, ScrollPaneConstants, Serializable
  49. {
  50.  
  51.     /** 
  52.      * The scrollpanes viewport child.  Default is an empty JViewport.
  53.      * @see JScrollPane#setViewport
  54.      */
  55.     protected JViewport viewport;
  56.  
  57.  
  58.     /**
  59.      * The scrollpanes vertical scrollbar child.  Default is a JScrollBar.
  60.      * @see JScrollPane#setVerticalScrollbar
  61.      */
  62.     protected JScrollBar vsb;
  63.  
  64.  
  65.     /**
  66.      * The scrollpanes horizontal scrollbar child.  Default is a JScrollBar.
  67.      * @see JScrollPane#setHorizontalScrollbar
  68.      */
  69.     protected JScrollBar hsb;
  70.  
  71.  
  72.     /** 
  73.      * The row header child.  Default is null.
  74.      * @see JScrollPane#setRowHeader
  75.      */
  76.     protected JViewport rowHead;
  77.  
  78.  
  79.     /** 
  80.      * The column header child.  Default is null.
  81.      * @see JScrollPane#setColumnHeader
  82.      */
  83.     protected JViewport colHead;
  84.  
  85.  
  86.     /**
  87.      * The component to display in the lower left corner.  Default is null.
  88.      * @see JScrollPane#setCorner
  89.      */
  90.     protected Component lowerLeft;
  91.  
  92.  
  93.     /**
  94.      * The component to display in the lower right corner.  Default is null.
  95.      * @see JScrollPane#setCorner
  96.      */
  97.     protected Component lowerRight;
  98.  
  99.  
  100.     /**
  101.      * The component to display in the upper left corner.  Default is null.
  102.      * @see JScrollPane#setCorner
  103.      */
  104.     protected Component upperLeft;
  105.  
  106.  
  107.     /**
  108.      * The component to display in the upper right corner.  Default is null.
  109.      * @see JScrollPane#setCorner
  110.      */
  111.     protected Component upperRight;
  112.  
  113.  
  114.     /** 
  115.      * The display policy for the vertical scrollbar.
  116.      * The default is JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED.  
  117.      * <p>
  118.      * This field is obsolete, please use the JScrollPane field instead.
  119.      * 
  120.      * @see JScrollPane#setVerticalScrollBarPolicy
  121.      */
  122.     protected int vsbPolicy = VERTICAL_SCROLLBAR_AS_NEEDED;
  123.  
  124.  
  125.     /**
  126.      * The display policy for the horizontal scrollbar.
  127.      * The default is JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED.
  128.      * <p>
  129.      * This field is obsolete, please use the JScrollPane field instead.
  130.      * 
  131.      * @see JScrollPane#setHorizontalScrollBarPolicy
  132.      */
  133.     protected int hsbPolicy = HORIZONTAL_SCROLLBAR_AS_NEEDED;
  134.  
  135.  
  136.     /**
  137.      * This method must be called after setting a JScrollPanes
  138.      * layout manager.  It initializes all of the internal fields that
  139.      * are ordinarily set by addLayoutComponent().  For example:
  140.      * <pre>
  141.      * ScrollPaneLayout mySPLayout = new ScrollPanelLayout() {
  142.      *     public void layoutContainer(Container p) {
  143.      *         super.layoutContainer(p);
  144.      *         // do some extra work here ...
  145.      *     }
  146.      * };
  147.      * scrollpane.setLayout(mySPLayout):
  148.      * mySPLayout.syncWithScrollPane(scrollpane);
  149.      * </pre>
  150.      */
  151.     public void syncWithScrollPane(JScrollPane sp) {
  152.     viewport = sp.getViewport();
  153.     vsb = sp.getVerticalScrollBar();
  154.     hsb = sp.getHorizontalScrollBar();
  155.     rowHead = sp.getRowHeader();
  156.     colHead = sp.getColumnHeader();
  157.     lowerLeft = sp.getCorner(LOWER_LEFT_CORNER);
  158.     lowerRight = sp.getCorner(LOWER_RIGHT_CORNER);
  159.     upperLeft = sp.getCorner(UPPER_LEFT_CORNER);
  160.     upperRight = sp.getCorner(UPPER_RIGHT_CORNER);
  161.     vsbPolicy = sp.getVerticalScrollBarPolicy();
  162.     hsbPolicy = sp.getHorizontalScrollBarPolicy();
  163.     }
  164.  
  165.  
  166.     /** 
  167.      * The method used to replace an existing component (if any) with a
  168.      * new one. Used to add each different kind of component to a JScrollPane,
  169.      * since there can be one and only one left corner, vertical scrollbar,
  170.      * and so on. So only one of each subcomponent is allowed, the old one
  171.      * is removed (if it exists) when a new one is added.
  172.      * 
  173.      * @param oldC the Component to replace
  174.      * @param newC the Component to add
  175.      */
  176.     protected Component addSingletonComponent(Component oldC, Component newC)
  177.     {
  178.     if ((oldC != null) && (oldC != newC)) {
  179.         oldC.getParent().remove(oldC);
  180.     }
  181.     return newC;
  182.     }
  183.  
  184.  
  185.     /**
  186.      * Adds the specified component to the layout. The layout is
  187.      * identified using one of:<ul>
  188.      * <li>JScrollPane.VIEWPORT
  189.      * <li>JScrollPane.VERTICAL_SCROLLBAR
  190.      * <li>JScrollPane.HORIZONTAL_SCROLLBAR
  191.      * <li>JScrollPane.ROW_HEADER
  192.      * <li>JScrollPane.COLUMN_HEADER
  193.      * <li>JScrollPane.LOWER_LEFT_CORNER
  194.      * <li>JScrollPane.LOWER_RIGHT_CORNER
  195.      * <li>JScrollPane.UPPER_LEFT_CORNER
  196.      * <li>JScrollPane.UPPER_RIGHT_CORNER
  197.      * </ul>
  198.      *
  199.      * @param s the component identifier
  200.      * @param comp the the component to be added
  201.      */
  202.     public void addLayoutComponent(String s, Component c) 
  203.     {
  204.     if (s.equals(VIEWPORT)) {
  205.         viewport = (JViewport)addSingletonComponent(viewport, c);
  206.     }
  207.     else if (s.equals(VERTICAL_SCROLLBAR)) {
  208.         vsb = (JScrollBar)addSingletonComponent(vsb, c);
  209.     }
  210.     else if (s.equals(HORIZONTAL_SCROLLBAR)) {
  211.         hsb = (JScrollBar)addSingletonComponent(hsb, c);
  212.     }
  213.     else if (s.equals(ROW_HEADER)) {
  214.         rowHead = (JViewport)addSingletonComponent(rowHead, c);
  215.     }
  216.     else if (s.equals(COLUMN_HEADER)) {
  217.         colHead = (JViewport)addSingletonComponent(colHead, c);
  218.     }
  219.     else if (s.equals(LOWER_LEFT_CORNER)) {
  220.         lowerLeft = addSingletonComponent(lowerLeft, c);
  221.     }
  222.     else if (s.equals(LOWER_RIGHT_CORNER)) {
  223.         lowerRight = addSingletonComponent(lowerRight, c);
  224.     }
  225.     else if (s.equals(UPPER_LEFT_CORNER)) {
  226.         upperLeft = addSingletonComponent(upperLeft, c);
  227.     }
  228.     else if (s.equals(UPPER_RIGHT_CORNER)) {
  229.         upperRight = addSingletonComponent(upperRight, c);
  230.     }
  231.     else {
  232.         throw new IllegalArgumentException("invalid layout key " + s);
  233.     }
  234.     }
  235.  
  236.  
  237.     /**
  238.      * Removes the specified component from the layout.
  239.      *   
  240.      * @param c the component to remove
  241.      */
  242.     public void removeLayoutComponent(Component c) 
  243.     {
  244.     if (c == viewport) {
  245.         viewport = null;
  246.     }
  247.     else if (c == vsb) {
  248.         vsb = null;
  249.     }
  250.     else if (c == hsb) {
  251.         hsb = null;
  252.     }
  253.     else if (c == rowHead) {
  254.         rowHead = null;
  255.     }
  256.     else if (c == colHead) {
  257.         colHead = null;
  258.     }
  259.     else if (c == lowerLeft) {
  260.         lowerLeft = null;
  261.     }
  262.     else if (c == lowerRight) {
  263.         lowerLeft = null;
  264.     }
  265.     else if (c == upperLeft) {
  266.         upperLeft = null;
  267.     }
  268.     else if (c == upperRight) {
  269.         upperRight = null;
  270.     }
  271.     }
  272.  
  273.  
  274.     /**
  275.      * Returns the vertical scrollbar-display policy.
  276.      *
  277.      * @return an int giving the display policy
  278.      * @see #setVerticalScrollBarPolicy
  279.      */
  280.     public int getVerticalScrollBarPolicy() {
  281.     return vsbPolicy;
  282.     }
  283.  
  284.  
  285.     /**
  286.      * Sets the vertical scrollbar-display policy. The options
  287.      * are:
  288.      * <ul>
  289.      * <li>JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED
  290.      * <li>JScrollPane.VERTICAL_SCROLLBAR_NEVER
  291.      * <li>JScrollPane.VERTICAL_SCROLLBAR_ALWAYS
  292.      * </ul>
  293.      * Note: Applications should use the JScrollPane version
  294.      * of this method.  It only exists for backwards compatibility
  295.      * with the Swing 1.0.2 (and earlier) versions of this class.
  296.      *
  297.      * @param x an int giving the display policy
  298.      */
  299.     public void setVerticalScrollBarPolicy(int x) {
  300.     switch (x) {
  301.     case VERTICAL_SCROLLBAR_AS_NEEDED:
  302.     case VERTICAL_SCROLLBAR_NEVER:
  303.     case VERTICAL_SCROLLBAR_ALWAYS:
  304.             vsbPolicy = x;
  305.         break;
  306.     default:
  307.         throw new IllegalArgumentException("invalid verticalScrollBarPolicy");
  308.     }
  309.     }
  310.  
  311.  
  312.     /**
  313.      * Returns the horizontal scrollbar-display policy.
  314.      *
  315.      * @return an int giving the display policy
  316.      * @see #setHorizontalScrollBarPolicy
  317.      */
  318.     public int getHorizontalScrollBarPolicy() {
  319.     return hsbPolicy;
  320.     }
  321.  
  322.     /**
  323.      * Sets the horizontal scrollbar-display policy.
  324.      * The options are:<ul>
  325.      * <li>JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED
  326.      * <li>JScrollPane.HOTRIZONTAL_SCROLLBAR_NEVER
  327.      * <li>JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS
  328.      * </ul>
  329.      * Note: Applications should use the JScrollPane version
  330.      * of this method.  It only exists for backwards compatibility
  331.      * with the Swing 1.0.2 (and earlier) versions of this class.
  332.      *
  333.      * @param x an int giving the display policy
  334.      */
  335.     public void setHorizontalScrollBarPolicy(int x) {
  336.     switch (x) {
  337.     case HORIZONTAL_SCROLLBAR_AS_NEEDED:
  338.     case HORIZONTAL_SCROLLBAR_NEVER:
  339.     case HORIZONTAL_SCROLLBAR_ALWAYS:
  340.             hsbPolicy = x;
  341.         break;
  342.     default:
  343.         throw new IllegalArgumentException("invalid horizontalScrollBarPolicy");
  344.     }
  345.     }
  346.  
  347.  
  348.     /**
  349.      * Returns the JViewport object that displays the scrollable contents.
  350.      * @return the JViewport object that displays the scrollable contents
  351.      * @see JScrollPane#getViewport
  352.      */
  353.     public JViewport getViewport() {
  354.     return viewport;
  355.     }
  356.  
  357.  
  358.     /**
  359.      * Returns the JScrollbar object that handles horizontal scrolling.
  360.      * @return the JScrollbar object that handles horizontal scrolling
  361.      * @see JScrollPane#getHorizontalScrollBar
  362.      */
  363.     public JScrollBar getHorizontalScrollBar() {
  364.     return hsb;
  365.     }
  366.  
  367.     /**
  368.      * Returns the JScrollbar object that handles vertical scrolling.
  369.      * @return the JScrollbar object that handles vertical scrolling
  370.      * @see JScrollPane#getVerticalScrollBar
  371.      */
  372.     public JScrollBar getVerticalScrollBar() {
  373.     return vsb;
  374.     }
  375.  
  376.  
  377.     /**
  378.      * Returns the JViewport object that is the row header.
  379.      * @return the JViewport object that is the row header
  380.      * @see JScrollPane#getRowHeader
  381.      */
  382.     public JViewport getRowHeader() {
  383.     return rowHead;
  384.     }
  385.  
  386.  
  387.     /**
  388.      * Returns the JViewport object that is the column header.
  389.      * @return the JViewport object that is the column header
  390.      * @see JScrollPane#getColumnHeader
  391.      */
  392.     public JViewport getColumnHeader() {
  393.     return colHead;
  394.     }
  395.  
  396.  
  397.     /**
  398.      * Returns the Component at the specified corner.
  399.      * @param key the String specifying the corner
  400.      * @return the Component at the specified corner, as defined in
  401.      *         {@link ScrollPaneConstants}
  402.      * @see JScrollPane#getCorner
  403.      */
  404.     public Component getCorner(String key) {
  405.     if (key.equals(LOWER_LEFT_CORNER)) {
  406.         return lowerLeft;
  407.     }
  408.     else if (key.equals(LOWER_RIGHT_CORNER)) {
  409.         return lowerRight;
  410.     }
  411.     else if (key.equals(UPPER_LEFT_CORNER)) {
  412.         return upperLeft;
  413.     }
  414.     else if (key.equals(UPPER_RIGHT_CORNER)) {
  415.         return upperRight;
  416.     }
  417.     else {
  418.         return null;
  419.     }
  420.     }
  421.  
  422.  
  423.     /** 
  424.      * The preferred size of a ScrollPane is the size of the insets,
  425.      * plus the preferred size of the viewport, plus the preferred size of 
  426.      * the visible headers, plus the preferred size of the scrollbars
  427.      * that will appear given the current view and the current
  428.      * scrollbar displayPolicies.  
  429.      * 
  430.      * @param parent the Container that will be laid out
  431.      * @return a Dimension object specifying the preferred size of the 
  432.      *         viewport and any scrollbars.
  433.      * @see ViewportLayout
  434.      * @see LayoutManager
  435.      */
  436.     public Dimension preferredLayoutSize(Container parent) 
  437.     {
  438.     /* Sync the (now obsolete) policy fields with the
  439.      * JScrollPane.
  440.      */
  441.     JScrollPane scrollPane = (JScrollPane)parent;
  442.     vsbPolicy = scrollPane.getVerticalScrollBarPolicy();
  443.     hsbPolicy = scrollPane.getHorizontalScrollBarPolicy();
  444.  
  445.     Insets insets = parent.getInsets();
  446.     int prefWidth = insets.left + insets.right;
  447.     int prefHeight = insets.top + insets.bottom;
  448.  
  449.     /* Note that viewport.getViewSize() is equivalent to 
  450.      * viewport.getView().getPreferredSize() modulo a null
  451.      * view or a view whose size was explicitly set.
  452.      */
  453.  
  454.     Dimension extentSize = null;
  455.     Dimension viewSize = null;
  456.     Component view = null;
  457.  
  458.     if (viewport !=  null) {
  459.         extentSize = viewport.getPreferredSize();
  460.         viewSize = viewport.getViewSize();
  461.         view = viewport.getView();
  462.     }
  463.  
  464.     /* If there's a viewport add its preferredSize.
  465.      */
  466.  
  467.     if (extentSize != null) {
  468.         prefWidth += extentSize.width;
  469.         prefHeight += extentSize.height;
  470.     }
  471.  
  472.     /* If there's a JScrollPane.viewportBorder, add its insets.
  473.      */
  474.  
  475.     Border viewportBorder = scrollPane.getViewportBorder();
  476.     if (viewportBorder != null) {
  477.         Insets vpbInsets = viewportBorder.getBorderInsets(parent);
  478.         prefWidth += vpbInsets.left + vpbInsets.right;
  479.         prefHeight += vpbInsets.top + vpbInsets.bottom;
  480.     }
  481.  
  482.     /* If a header exists and it's visible, factor its
  483.      * preferred size in.
  484.      */
  485.  
  486.     if ((rowHead != null) && rowHead.isVisible()) {
  487.         prefWidth += rowHead.getPreferredSize().width;
  488.     }
  489.  
  490.     if ((colHead != null) && colHead.isVisible()) {
  491.         prefHeight += colHead.getPreferredSize().height;
  492.     }
  493.  
  494.     /* If a scrollbar is going to appear, factor its preferred size in.
  495.      * If the scrollbars policy is AS_NEEDED, this can be a little
  496.      * tricky:
  497.      * 
  498.      * - If the view is a Scrollable then scrollableTracksViewportWidth
  499.      * and scrollableTracksViewportHeight can be used to effectively 
  500.      * disable scrolling (if they're true) in their respective dimensions.
  501.      * 
  502.      * - Assuming that a scrollbar hasn't been disabled by the 
  503.      * previous constraint, we need to decide if the scrollbar is going 
  504.      * to appear to correctly compute the JScrollPanes preferred size.
  505.      * To do this we compare the preferredSize of the viewport (the 
  506.      * extentSize) to the preferredSize of the view.  Although we're
  507.      * not responsible for laying out the view we'll assume that the 
  508.      * JViewport will always give it its preferredSize.
  509.      */
  510.  
  511.     if ((vsb != null) && (vsbPolicy != VERTICAL_SCROLLBAR_NEVER)) {
  512.         if (vsbPolicy == VERTICAL_SCROLLBAR_ALWAYS) {
  513.         prefWidth += vsb.getPreferredSize().width;
  514.         }
  515.         else if ((viewSize != null) && (extentSize != null)) {
  516.         boolean canScroll = true;
  517.         if (view instanceof Scrollable) {
  518.             canScroll = !((Scrollable)view).getScrollableTracksViewportHeight();
  519.         }
  520.         if (canScroll && (viewSize.height > extentSize.height)) {
  521.             prefWidth += vsb.getPreferredSize().width;
  522.         }
  523.         }
  524.     }
  525.  
  526.     if ((hsb != null) && (hsbPolicy != HORIZONTAL_SCROLLBAR_NEVER)) {
  527.         if (hsbPolicy == HORIZONTAL_SCROLLBAR_ALWAYS) {
  528.         prefHeight += hsb.getPreferredSize().height;
  529.         }
  530.         else if ((viewSize != null) && (extentSize != null)) {
  531.         boolean canScroll = true;
  532.         if (view instanceof Scrollable) {
  533.             canScroll = !((Scrollable)view).getScrollableTracksViewportWidth();
  534.         }
  535.         if (canScroll && (viewSize.width > extentSize.width)) {
  536.             prefHeight += hsb.getPreferredSize().height;
  537.         }
  538.         }
  539.     }
  540.  
  541.     return new Dimension(prefWidth, prefHeight);
  542.     }
  543.  
  544.  
  545.     /** 
  546.      * The minimum size of a ScrollPane is the size of the insets 
  547.      * plus minimum size of the viewport, plus the scrollpane's
  548.      * viewportBorder insets, plus the minimum size 
  549.      * of the visible headers, plus the minimum size of the 
  550.      * scrollbars whose displayPolicy isn't NEVER.
  551.      * 
  552.      * @param parent the Container that will be laid out
  553.      * @return a Dimension object specifying the minimum size
  554.      */
  555.     public Dimension minimumLayoutSize(Container parent) 
  556.     {
  557.     /* Sync the (now obsolete) policy fields with the
  558.      * JScrollPane.
  559.      */
  560.     JScrollPane scrollPane = (JScrollPane)parent;
  561.     vsbPolicy = scrollPane.getVerticalScrollBarPolicy();
  562.     hsbPolicy = scrollPane.getHorizontalScrollBarPolicy();
  563.  
  564.     Insets insets = parent.getInsets();
  565.     int minWidth = insets.left + insets.right;
  566.     int minHeight = insets.top + insets.bottom;
  567.     
  568.     /* If there's a viewport add its minimumSize.
  569.      */
  570.     
  571.     if (viewport != null) {
  572.         Dimension size = viewport.getMinimumSize();
  573.         minWidth += size.width;
  574.         minHeight += size.height;
  575.     }
  576.  
  577.     /* If there's a JScrollPane.viewportBorder, add its insets.
  578.      */
  579.  
  580.     Border viewportBorder = scrollPane.getViewportBorder();
  581.     if (viewportBorder != null) {
  582.         Insets vpbInsets = viewportBorder.getBorderInsets(parent);
  583.         minWidth += vpbInsets.left + vpbInsets.right;
  584.         minHeight += vpbInsets.top + vpbInsets.bottom;
  585.     }
  586.  
  587.     /* If a header exists and it's visible, factor its
  588.      * minimum size in.
  589.      */
  590.  
  591.     if ((rowHead != null) && rowHead.isVisible()) {
  592.         Dimension size = rowHead.getMinimumSize();
  593.         minWidth += size.width;
  594.         minHeight = Math.max(minHeight, size.height);
  595.     }
  596.  
  597.     if ((colHead != null) && colHead.isVisible()) {
  598.         Dimension size = colHead.getMinimumSize();
  599.         minWidth = Math.max(minWidth, size.width);
  600.         minHeight += size.height;
  601.     }
  602.  
  603.     /* If a scrollbar might appear, factor its minimum
  604.      * size in.
  605.      */
  606.  
  607.     if ((vsb != null) && (vsbPolicy != VERTICAL_SCROLLBAR_NEVER)) {
  608.         Dimension size = vsb.getMinimumSize();
  609.         minWidth += size.width;
  610.         minHeight = Math.max(minHeight, size.height);
  611.     }
  612.  
  613.     if ((hsb != null) && (hsbPolicy != VERTICAL_SCROLLBAR_NEVER)) {
  614.         Dimension size = hsb.getMinimumSize();
  615.         minWidth = Math.max(minWidth, size.width);
  616.         minHeight += size.height;
  617.     }
  618.  
  619.     return new Dimension(minWidth, minHeight);
  620.     }
  621.  
  622.  
  623.     /** 
  624.      * Lay out the scrollpane. The positioning of components depends on
  625.      * the following constraints:
  626.      * <ul>
  627.      * <li> The row header, if present and visible, gets its preferred
  628.      * height and the viewports width.
  629.      * 
  630.      * <li> The column header, if present and visible, gets its preferred
  631.      * width and the viewports height.
  632.      * 
  633.      * <li> If a vertical scrollbar is needed, i.e. if the viewports extent
  634.      * height is smaller than its view height or if the displayPolicy
  635.      * is ALWAYS, it's treated like the row header wrt it's dimensions and
  636.      * it's made visible.
  637.      * 
  638.      * <li> If a horizontal scrollbar is needed it's treated like the
  639.      * column header (and see the vertical scrollbar item).
  640.      * 
  641.      * <li> If the scrollpane has a non-null viewportBorder, then space
  642.      * is allocated for that.
  643.      * 
  644.      * <li> The viewport gets the space available after accounting for
  645.      * the previous constraints.
  646.      * 
  647.      * <li> The corner components, if provided, are aligned with the 
  648.      * ends of the scrollbars and headers. If there's a vertical
  649.      * scrollbar the right corners appear, if there's a horizontal
  650.      * scrollbar the lower corners appear, a row header gets left
  651.      * corners and a column header gets upper corners.
  652.      * </ul>
  653.      *
  654.      * @param parent the Container to lay out
  655.      */
  656.     public void layoutContainer(Container parent) 
  657.     {
  658.     /* Sync the (now obsolete) policy fields with the
  659.      * JScrollPane.
  660.      */
  661.     JScrollPane scrollPane = (JScrollPane)parent;
  662.     vsbPolicy = scrollPane.getVerticalScrollBarPolicy();
  663.     hsbPolicy = scrollPane.getHorizontalScrollBarPolicy();
  664.  
  665.     Rectangle availR = new Rectangle(scrollPane.getSize());
  666.  
  667.     Insets insets = parent.getInsets();
  668.     availR.x = insets.left;
  669.     availR.y = insets.top;
  670.     availR.width -= insets.left + insets.right;
  671.     availR.height -= insets.top + insets.bottom;
  672.  
  673.  
  674.     /* If there's a visible column header remove the space it 
  675.      * needs from the top of availR.  The column header is treated 
  676.      * as if it were fixed height, arbitrary width.
  677.      */
  678.  
  679.     Rectangle colHeadR = new Rectangle(0, availR.y, 0, 0);
  680.  
  681.     if ((colHead != null) && (colHead.isVisible())) {
  682.         int colHeadHeight = colHead.getPreferredSize().height;
  683.         colHeadR.height = colHeadHeight; 
  684.         availR.y += colHeadHeight;
  685.         availR.height -= colHeadHeight;
  686.     }
  687.  
  688.     /* If there's a visible row header remove the space it needs
  689.      * from the left of availR.  The row header is treated 
  690.      * as if it were fixed width, arbitrary height.
  691.      */
  692.  
  693.     Rectangle rowHeadR = new Rectangle(availR.x, 0, 0, 0);
  694.     
  695.     if ((rowHead != null) && (rowHead.isVisible())) {
  696.         int rowHeadWidth = rowHead.getPreferredSize().width;
  697.         rowHeadR.width = rowHeadWidth;
  698.         availR.x += rowHeadWidth;
  699.         availR.width -= rowHeadWidth;
  700.     }
  701.  
  702.     /* If there's a JScrollPane.viewportBorder, remove the
  703.      * space it occupies for availR.
  704.      */
  705.  
  706.     Border viewportBorder = scrollPane.getViewportBorder();
  707.     Insets vpbInsets;
  708.     if (viewportBorder != null) {
  709.         vpbInsets = viewportBorder.getBorderInsets(parent);
  710.         availR.x += vpbInsets.left;
  711.         availR.y += vpbInsets.top;
  712.         availR.width -= vpbInsets.left + vpbInsets.right;
  713.         availR.height -= vpbInsets.top + vpbInsets.bottom;
  714.     }
  715.     else {
  716.         vpbInsets = new Insets(0,0,0,0);
  717.     }
  718.  
  719.     colHeadR.x = availR.x;
  720.     rowHeadR.y = availR.y;
  721.  
  722.     /* At this point availR is the space available for the viewport
  723.      * and scrollbars, and the rowHeadR colHeadR rectangles are correct
  724.      * except for their width and height respectively.  Once we're 
  725.      * through computing the dimensions  of these three parts we can 
  726.      * go back and set the dimensions of rowHeadR.width, colHeadR.height, 
  727.      * and the bounds for the corners.
  728.      * 
  729.          * We'll decide about putting up scrollbars by comparing the 
  730.          * viewport views preferred size with the viewports extent
  731.      * size (generally just its size).  Using the preferredSize is
  732.      * reasonable because layout proceeds top down - so we expect
  733.      * the viewport to be layed out next.  And we assume that the
  734.      * viewports layout manager will give the view it's preferred
  735.      * size.  One exception to this is when the view implements 
  736.      * Scrollable and Scrollable.getViewTracksViewport{Width,Height}
  737.      * methods return true.  If the view is tracking the viewports
  738.      * width we don't bother with a horizontal scrollbar, similarly
  739.      * if view.getViewTracksViewport(Height) is true we don't bother
  740.      * with a vertical scrollbar.
  741.      */
  742.  
  743.     Component view = (viewport != null) ? viewport.getView() : null;
  744.     Dimension viewPrefSize =  
  745.         (view != null) ? view.getPreferredSize() 
  746.                            : new Dimension(0,0);
  747.  
  748.     Dimension extentSize = 
  749.         (viewport != null) ? viewport.toViewCoordinates(availR.getSize()) 
  750.                            : new Dimension(0,0);
  751.  
  752.     boolean viewTracksViewportWidth = false;
  753.     boolean viewTracksViewportHeight = false;
  754.     if (view instanceof Scrollable) {
  755.         Scrollable sv = ((Scrollable)view);
  756.         viewTracksViewportWidth = sv.getScrollableTracksViewportWidth();
  757.         viewTracksViewportHeight = sv.getScrollableTracksViewportHeight();
  758.     }
  759.  
  760.     /* If there's a vertical scrollbar and we need one, allocate
  761.      * space for it (we'll make it visible later). A vertical 
  762.      * scrollbar is considered to be fixed width, arbitrary height.
  763.      */
  764.  
  765.     Rectangle vsbR = new Rectangle(0, availR.y - vpbInsets.top, 0, 0);
  766.  
  767.     boolean vsbNeeded;
  768.     if (vsbPolicy == VERTICAL_SCROLLBAR_ALWAYS) {
  769.         vsbNeeded = true;
  770.     }
  771.     else if (vsbPolicy == VERTICAL_SCROLLBAR_NEVER) {
  772.         vsbNeeded = false;
  773.     }
  774.     else {  // vsbPolicy == VERTICAL_SCROLLBAR_AS_NEEDED
  775.         vsbNeeded = !viewTracksViewportHeight && (viewPrefSize.height > extentSize.height);
  776.     }
  777.  
  778.  
  779.     if ((vsb != null) && vsbNeeded) {
  780.         int vsbWidth = vsb.getPreferredSize().width;
  781.         availR.width -= vsbWidth;
  782.         vsbR.x = availR.x + availR.width + vpbInsets.right;
  783.         vsbR.width = vsbWidth;
  784.     }
  785.     
  786.     /* If there's a horizontal scrollbar and we need one, allocate
  787.      * space for it (we'll make it visible later). A horizontal 
  788.      * scrollbar is considered to be fixed height, arbitrary width.
  789.      */
  790.  
  791.     Rectangle hsbR = new Rectangle(availR.x - vpbInsets.left, 0, 0, 0);
  792.     boolean hsbNeeded;
  793.     if (hsbPolicy == HORIZONTAL_SCROLLBAR_ALWAYS) {
  794.         hsbNeeded = true;
  795.     }
  796.     else if (hsbPolicy == HORIZONTAL_SCROLLBAR_NEVER) {
  797.         hsbNeeded = false;
  798.     }
  799.     else {  // hsbPolicy == HORIZONTAL_SCROLLBAR_AS_NEEDED
  800.         hsbNeeded = !viewTracksViewportWidth && (viewPrefSize.width > extentSize.width);
  801.     }
  802.  
  803.     if ((hsb != null) && hsbNeeded) {
  804.         int hsbHeight = hsb.getPreferredSize().height;
  805.         availR.height -= hsbHeight;
  806.         hsbR.y = availR.y + availR.height + vpbInsets.bottom;
  807.         hsbR.height = hsbHeight;
  808.     
  809.         /* If we added the horizontal scrollbar then we've implicitly 
  810.          * reduced  the vertical space available to the viewport. 
  811.          * As a consequence we may have to add the vertical scrollbar, 
  812.          * if that hasn't been done so already.  Ofcourse we
  813.          * don't bother with any of this if the vsbPolicy is NEVER.
  814.          */
  815.         if ((vsb != null) && !vsbNeeded && (vsbPolicy != VERTICAL_SCROLLBAR_NEVER)) {
  816.         extentSize = viewport.toViewCoordinates(availR.getSize());
  817.         vsbNeeded = viewPrefSize.height > extentSize.height;
  818.  
  819.         if (vsbNeeded) {
  820.             int vsbWidth = vsb.getPreferredSize().width;
  821.             availR.width -= vsbWidth;
  822.             vsbR.x = availR.x + availR.width + vpbInsets.right;
  823.             vsbR.width = vsbWidth;
  824.         }
  825.         }
  826.     }
  827.  
  828.     /* We now have the final size of the viewport: availR.
  829.      * Now fixup the header and scrollbar widths/heights.
  830.      */
  831.     
  832.     vsbR.height = availR.height + vpbInsets.top + vpbInsets.bottom;
  833.     hsbR.width = availR.width + vpbInsets.left + vpbInsets.right;
  834.     rowHeadR.height = availR.height;
  835.     colHeadR.width = availR.width;
  836.  
  837.     /* Set the bounds of all nine components.  The scrollbars
  838.      * are made invisible if they're not needed.
  839.      */
  840.     
  841.     if (viewport != null) {
  842.         viewport.setBounds(availR);
  843.     }
  844.  
  845.     if (rowHead != null) {
  846.         rowHead.setBounds(rowHeadR);
  847.     }
  848.  
  849.     if (colHead != null) {
  850.         colHead.setBounds(colHeadR);
  851.     }
  852.  
  853.     if (vsb != null) {
  854.         if (vsbNeeded) {
  855.         vsb.setVisible(true);
  856.         vsb.setBounds(vsbR);
  857.         }
  858.         else {
  859.         vsb.setVisible(false);
  860.         }
  861.     }
  862.  
  863.     if (hsb != null) {
  864.         if (hsbNeeded) {
  865.         hsb.setVisible(true);
  866.         hsb.setBounds(hsbR);
  867.         }
  868.         else {
  869.         hsb.setVisible(false);
  870.         }
  871.     }
  872.  
  873.     if (lowerLeft != null) {
  874.         lowerLeft.setBounds(rowHeadR.x, hsbR.y, rowHeadR.width, hsbR.height);
  875.     }
  876.  
  877.     if (lowerRight != null) {
  878.         lowerRight.setBounds(vsbR.x, hsbR.y, vsbR.width, hsbR.height);
  879.     }
  880.  
  881.     if (upperLeft != null) {
  882.         upperLeft.setBounds(rowHeadR.x, colHeadR.y, rowHeadR.width, colHeadR.height);
  883.     }
  884.  
  885.     if (upperRight != null) {
  886.         upperRight.setBounds(vsbR.x, colHeadR.y, vsbR.width, colHeadR.height);
  887.     }
  888.     }
  889.     
  890.  
  891.     /** 
  892.      * Returns the bounds of the border around the specified scroll pane's 
  893.      * viewport.
  894.      *
  895.      * @return the size and position of the viewport border
  896.      * @deprecated As of JDK version Swing1.1
  897.      *    replaced by <code>JScrollPane.getViewportBorderBounds()</code>.
  898.      */
  899.     public Rectangle getViewportBorderBounds(JScrollPane scrollpane) {
  900.     return scrollpane.getViewportBorderBounds();
  901.     }
  902.  
  903.     /**
  904.      * The UI resource version of ScrollPaneLayout.
  905.      */
  906.     public static class UIResource extends ScrollPaneLayout implements javax.swing.plaf.UIResource {}
  907. }
  908.